package com.lgy.common.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

@Component
public class DistributedLock {
    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final Long RELEASE_SUCCESS = 1L;
    /**
     * 获得锁
     */
    public boolean getLock(String lockId, String requestId, long millisecond) {
        Boolean success = redisTemplate.opsForValue().setIfAbsent(lockId, requestId, millisecond, TimeUnit.MILLISECONDS);
        return success != null && success;
    }

    /**
     * 释放锁
     * @param lockId
     */
    public boolean releaseLock(String lockId, String requestId) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Collections.singletonList(lockId), requestId);
        if(RELEASE_SUCCESS.equals(result)) {
            return true;
        }
        return false;
    }


    public void execLuaScript() {
        Object res = redisTemplate.execute(this.getRedisLockScript(), Collections.singletonList("fengc"),"1000*10");
        System.out.println(res);
    }

    protected RedisScript<Long> getRedisLockScript() {
        //String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end ";

        String script = "local key = KEYS[1];local expiration = ARGV[2];local value = 1;";
        script += "if redis.call('EXISTS', key) == 1 then return -1 else redis.call('SET', key, value);redis.call('EXPIRE', key, expiration);return 1;end";
        return new DefaultRedisScript<>(script, Long.class);
    }
}
